package com.jandar.gui;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * 状态栏包装类。 
 * 实现状态栏的信息是否滚动。 
 * 实现从左到右移动和从右到左移动。 
 * 实现鼠标移动到信息上面后会停止滚动。
 * 
 * @author pqj
 * @version 2009-7-27
 */
public class DeckStatusBar extends JPanel {
	/** serialVersionUID */
	private static final long serialVersionUID = -5125436747394240645L;

	/** 滚动栏使用空格填充（150个半角空格） */
	private String mqrqueeFill = "                                                                                                                                                      ";

	/** 显示标签 */
	private JLabel label = new JLabel();

	/** 延迟毫秒数 */
	private long delay = 100;

	/** 是否滚动 */
	private boolean marquee = false;

	/** 从左到右滚动 */
	private boolean leftToRight = true;

	/** 滚动使用的线程 */
	private ProgressBarThread marqueeThread = null;

	/** 要显示的内容 */
	private String text = "";

	public DeckStatusBar() {
		this(100, false, false);
	}

	public DeckStatusBar(boolean marquee, boolean leftToRight) {
		this(100, marquee, leftToRight);
	}

	public DeckStatusBar(long delay, boolean marquee, boolean leftToRight) {
		this.delay = delay;
		this.marquee = marquee;
		this.leftToRight = leftToRight;
		label.setOpaque(false);
		if (leftToRight) {
			this.setLayout(new FlowLayout(FlowLayout.LEFT));
		} else {
			this.setLayout(new FlowLayout(FlowLayout.RIGHT));
		}
		this.add(label);
		initLabel(this.text);
		if (marquee) {
			marqueeThread = new ProgressBarThread();
			marqueeThread.setDaemon(true);
			marqueeThread.start();
		}

		label.addMouseListener(new MouseAdapter() {
			public void mouseEntered(MouseEvent e) {
				pauseMarqueeThread();
			}

			public void mouseExited(MouseEvent e) {
				startMarqueeThread();
			}
		});
	}

	private void initLabel(String text) {
		if (marquee) {
			if (leftToRight) {
				this.label.setText(mqrqueeFill + text);
			} else {
				this.label.setText(text + mqrqueeFill);
			}
		} else {
			this.label.setText(text);
		}
	}

	protected void paintComponent(Graphics g) {
		super.paintComponent(g);

		int y = 0;
		g.setColor(new Color(156, 154, 140));
		g.drawLine(0, y, getWidth(), y);
		y++;
		g.setColor(new Color(196, 194, 183));
		g.drawLine(0, y, getWidth(), y);
	}

	public long getDelay() {
		return delay;
	}

	public boolean isMarquee() {
		return marquee;
	}

	public boolean isLeftToRight() {
		return leftToRight;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
		initLabel(text);
	}

	public void setLabelFont(Font font) {
		this.label.setFont(font);
	}

	public void setLabelColor(Color color) {
		this.label.setForeground(color);
	}

	public String getMqrqueeFill() {
		return mqrqueeFill;
	}

	public void setMqrqueeFill(String mqrqueeFill) {
		this.mqrqueeFill = mqrqueeFill;
		initLabel(text);
	}

	public void pauseMarqueeThread() {
		if (marqueeThread != null && marqueeThread.isAlive()) {
			marqueeThread.setPause(true);
		}
	}

	public void startMarqueeThread() {
		if (marqueeThread != null && marqueeThread.isAlive()) {
			marqueeThread.setPause(false);
			resumeProgressBarThread();
		}
	}

	private synchronized void suspendProgressBarThread() {
		try {
			wait();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public synchronized void resumeProgressBarThread() {
		notifyAll();
	}

	class ProgressBarThread extends Thread {

		private boolean pause = false;

		public void run() {
			while (!this.isInterrupted() && marquee) {
				if (pause) {
					suspendProgressBarThread();
				}

				String textStr = label.getText();
				if (textStr.length() > 1) {
					if (leftToRight) {
						textStr = textStr.substring(1);
					} else {
						textStr = textStr.substring(0, textStr.length() - 1);
					}
					label.setText(textStr);
				} else {
					initLabel(text);
				}
				try {
					sleep(delay);
				} catch (InterruptedException ex) {
					this.interrupt();
				}
			}
		}

		public boolean isPause() {
			return pause;
		}

		public void setPause(boolean pause) {
			this.pause = pause;
		}

		public void exit() {
			this.interrupt();
		}
	}
}
